package com.itboy.mall.pms.spuinfo.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.itboy.common.core.domain.entity.es.SkuEsModel;
import com.itboy.common.exception.CustomException;
import com.itboy.common.utils.PageUtils;
import com.itboy.common.core.page.PagePlus;
import com.itboy.common.core.page.TableDataInfo;
import com.itboy.mall.pms.attr.constant.AttrEnum;
import com.itboy.mall.pms.attr.domain.MallAttr;
import com.itboy.mall.pms.attr.service.IMallAttrService;
import com.itboy.mall.pms.spuinfo.constant.SpuEnum;
import com.itboy.mall.sms.bounds.domain.MallSpuBounds;
import com.itboy.mall.sms.bounds.service.IMallSpuBoundsService;
import com.itboy.mall.pms.brand.domain.MallBrand;
import com.itboy.mall.pms.brand.service.IMallBrandService;
import com.itboy.mall.pms.category.domain.MallCategory;
import com.itboy.mall.pms.category.service.IMallCategoryService;
import com.itboy.mall.sms.memberprice.domain.MallMemberPrice;
import com.itboy.mall.sms.memberprice.service.IMallMemberPriceService;
import com.itboy.mall.pms.productattrvalue.domain.MallProductAttrValue;
import com.itboy.mall.pms.productattrvalue.service.IMallProductAttrValueService;
import com.itboy.mall.sms.skufullreduction.domain.MallSkuFullReduction;
import com.itboy.mall.sms.skufullreduction.service.IMallSkuFullReductionService;
import com.itboy.mall.pms.skuimages.domain.MallSkuImages;
import com.itboy.mall.pms.skuimages.service.IMallSkuImagesService;
import com.itboy.mall.pms.skuinfo.domain.MallSkuInfo;
import com.itboy.mall.pms.skuinfo.service.IMallSkuInfoService;
import com.itboy.mall.sms.skuladder.domain.MallSkuLadder;
import com.itboy.mall.sms.skuladder.service.IMallSkuLadderService;
import com.itboy.mall.pms.skusaleattrvalue.domain.MallSkuSaleAttrValue;
import com.itboy.mall.pms.skusaleattrvalue.service.IMallSkuSaleAttrValueService;
import com.itboy.mall.pms.spuimages.domain.MallSpuImages;
import com.itboy.mall.pms.spuimages.service.IMallSpuImagesService;
import com.itboy.mall.pms.spuinfodesc.domain.MallSpuInfoDesc;
import com.itboy.mall.pms.spuinfodesc.service.IMallSpuInfoDescService;
import com.itboy.mall.wms.waresku.service.IMallWareSkuService;
import com.itboy.mall.wms.waresku.vo.SkuHasStockVo;
import com.itboy.search.service.EsProductSaveService;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.itboy.common.core.mybatisplus.core.ServicePlusImpl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.itboy.mall.pms.spuinfo.bo.MallSpuInfoAddBo;
import com.itboy.mall.pms.spuinfo.bo.MallSpuInfoQueryBo;
import com.itboy.mall.pms.spuinfo.bo.MallSpuInfoEditBo;
import com.itboy.mall.pms.spuinfo.domain.MallSpuInfo;
import com.itboy.mall.pms.spuinfo.mapper.MallSpuInfoMapper;
import com.itboy.mall.pms.spuinfo.vo.MallSpuInfoVo;
import com.itboy.mall.pms.spuinfo.service.IMallSpuInfoService;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Collection;
import java.util.stream.Collectors;

/**
 * spu信息Service业务层处理
 *
 * @author itboy
 * @date 2021-07-31
 */
@Service
public class MallSpuInfoServiceImpl extends ServicePlusImpl<MallSpuInfoMapper, MallSpuInfo> implements IMallSpuInfoService {

	@Autowired
	private IMallBrandService iMallBrandService;

	@Autowired
	private IMallCategoryService iMallCategoryService;

	@Autowired
	private IMallSpuInfoService iMallSpuInfoService;

	/**
	 * sup 保存图集 service
	 */
	@Autowired
	private IMallSpuImagesService iMallSpuImagesService;

	/**
	 * sup 保存描述图集 service
	 */
	@Autowired
	private IMallSpuInfoDescService iMallSpuInfoDescService;

	/**
	 * spu 保存规格参数 service
	 */
	@Autowired
	private IMallProductAttrValueService iMallProductAttrValueService;

	/**
	 * spu 积分 service
	 */
	@Autowired
	private IMallSpuBoundsService iMallSpuBoundsService;

	/**
	 * sku service
	 */
	@Autowired
	private IMallSkuInfoService iMallSkuInfoService;

	/**
	 * sku 保存销售属性 service
	 */
	@Autowired
	private IMallSkuSaleAttrValueService iMallSkuSaleAttrValueService;

	/**
	 * sku 保存图集 service
	 */
	@Autowired
	private IMallSkuImagesService iMallSkuImagesService;

	/**
	 * sku 商品满减信息 service
	 */
	@Autowired
	private IMallSkuFullReductionService iMallSkuFullReductionService;


	/**
	 * sku 商品阶梯价格  满几件打几折 service
	 */
	@Autowired
	private IMallSkuLadderService iMallSkuLadderService;

	/**
	 * sku 商品会员价格 service
	 */
	@Autowired
	private IMallMemberPriceService iMallMemberPriceService;

	/**
	 * 属性service
	 */
	@Autowired
	private IMallAttrService iMallAttrService;

	/**
	 * 库存
	 */
	@Autowired
	private IMallWareSkuService iMallWareSkuService;

	@Autowired
	private EsProductSaveService esProductSaveService;


    @Override
    public MallSpuInfoVo queryById(Long id){
        return getVoById(id, MallSpuInfoVo.class);
    }

    @Override
    public TableDataInfo<MallSpuInfoVo> queryPageList(MallSpuInfoQueryBo bo) {
        PagePlus<MallSpuInfo, MallSpuInfoVo> result = pageVo(PageUtils.buildPagePlus(), buildQueryWrapper(bo), MallSpuInfoVo.class);
		List<MallSpuInfoVo> recordsVo = result.getRecordsVo();
		if(CollectionUtil.isNotEmpty(recordsVo)){
			//分类
			List<Long> catalogIdList = recordsVo.stream().map(e -> e.getCatalogId()).collect(Collectors.toList());
			LambdaQueryWrapper<MallCategory> catalogWrapper = new LambdaQueryWrapper<>();
			catalogWrapper.in(MallCategory::getId,catalogIdList);
			List<MallCategory> mallCategoryList = iMallCategoryService.list(catalogWrapper);
			recordsVo.forEach(e->{
				MallCategory mallCategory = mallCategoryList.stream().filter(t -> t.getId().equals(e.getCatalogId())).findFirst().orElse(null);
				if(ObjectUtil.isNotNull(mallCategory)){
					e.setCatalogName(mallCategory.getName());
				}
			});

			//品牌
			List<Long> brandIdList = recordsVo.stream().map(e -> e.getBrandId()).collect(Collectors.toList());
			LambdaQueryWrapper<MallBrand> brandWrapper = new LambdaQueryWrapper<>();
			brandWrapper.in(MallBrand::getBrandId,brandIdList);
			List<MallBrand> mallBrandList = iMallBrandService.list(brandWrapper);

			recordsVo.forEach(e->{
				MallBrand mallBrand = mallBrandList.stream().filter(t -> t.getBrandId().equals(e.getBrandId())).findFirst().orElse(null);
				if(ObjectUtil.isNotNull(mallBrand)){
					e.setBrandName(mallBrand.getName());
				}
			});
		}
		result.setRecordsVo(recordsVo);
		return PageUtils.buildDataInfo(result);
    }

    @Override
    public List<MallSpuInfoVo> queryList(MallSpuInfoQueryBo bo) {
        return listVo(buildQueryWrapper(bo), MallSpuInfoVo.class);
    }

    private LambdaQueryWrapper<MallSpuInfo> buildQueryWrapper(MallSpuInfoQueryBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<MallSpuInfo> lqw = Wrappers.lambdaQuery();
        lqw.like(StrUtil.isNotBlank(bo.getSpuName()), MallSpuInfo::getSpuName, bo.getSpuName());
        lqw.eq(bo.getCatalogId() != null, MallSpuInfo::getCatalogId, bo.getCatalogId());
        lqw.eq(bo.getBrandId() != null, MallSpuInfo::getBrandId, bo.getBrandId());
        lqw.eq(bo.getPublishStatus() != null, MallSpuInfo::getPublishStatus, bo.getPublishStatus());
        return lqw;
    }

    @Override
    public Boolean insertByAddBo(MallSpuInfoAddBo bo) {
        MallSpuInfo add = BeanUtil.toBean(bo, MallSpuInfo.class);
        validEntityBeforeSave(add);
        return save(add);
    }

    @Override
    public Boolean updateByEditBo(MallSpuInfoEditBo bo) {
        MallSpuInfo update = BeanUtil.toBean(bo, MallSpuInfo.class);
        validEntityBeforeSave(update);
        return updateById(update);
    }

    /**
     * 保存前的数据校验
     *
     * @param entity 实体类数据
     */
    private void validEntityBeforeSave(MallSpuInfo entity){
        //TODO 做一些数据校验,如唯一约束
    }

    @Override
	@Transactional
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {

		//删除 spu描述 mall_spu_info_desc
		iMallSpuInfoDescService.remove(new LambdaQueryWrapper<MallSpuInfoDesc>().in(MallSpuInfoDesc::getSpuId,ids));
		//删除 spu图集 mall_spu_images
		iMallSpuImagesService.remove(new LambdaQueryWrapper<MallSpuImages>().in(MallSpuImages::getSpuId,ids));
		//删除 spu 规格参数 mall_product_attr_value
		iMallProductAttrValueService.remove(new LambdaQueryWrapper<MallProductAttrValue>().in(MallProductAttrValue::getSpuId,ids));
		//删除 spu 积分信息 mall_spu_bounds
		iMallSpuBoundsService.remove(new LambdaQueryWrapper<MallSpuBounds>().in(MallSpuBounds::getSpuId,ids));
        //查询sku信息列表
		List<MallSkuInfo> skuInfoList = iMallSkuInfoService.list(new LambdaQueryWrapper<MallSkuInfo>().in(MallSkuInfo::getSpuId, ids));
		if(CollectionUtil.isNotEmpty(skuInfoList)){
			List<Long> skuListIds = skuInfoList.stream().map(e -> e.getSkuId()).collect(Collectors.toList());
			//删除 skuInfo信息
			iMallSkuInfoService.remove(new LambdaQueryWrapper<MallSkuInfo>().in(MallSkuInfo::getSkuId,skuListIds));
			//刪除 mall_sku_images
			iMallSkuImagesService.remove(new LambdaQueryWrapper<MallSkuImages>().in(MallSkuImages::getSkuId,skuListIds));
			//刪除 mall_sku_sale_attr_value 銷售属性
			iMallSkuSaleAttrValueService.remove(new LambdaQueryWrapper<MallSkuSaleAttrValue>().in(MallSkuSaleAttrValue::getSkuId,skuListIds));
			//刪除 mall_sku_ladder 满减信息 满几件打几折
			iMallSkuLadderService.remove(new LambdaQueryWrapper<MallSkuLadder>().in(MallSkuLadder::getSkuId,skuListIds));
			//删除 mall_member_price 会员价格
			iMallMemberPriceService.remove(new LambdaQueryWrapper<MallMemberPrice>().in(MallMemberPrice::getSkuId,skuListIds));
			//删除 mall_sku_full_reduction 满减信息
			iMallSkuFullReductionService.remove(new LambdaQueryWrapper<MallSkuFullReduction>().in(MallSkuFullReduction::getSkuId,skuListIds));
		}
		//删除 spuInfo 信息
        return removeByIds(ids);
    }

	@Override
	public MallSpuInfoVo queryInfoById(Long id) {
		MallSpuInfoVo mallSpuInfoVo = iMallSpuInfoService.queryById(id);
		String[] recursionById = iMallCategoryService.getRecursionById(mallSpuInfoVo.getCatalogId());
		mallSpuInfoVo.setCatalogIds(recursionById);
		return mallSpuInfoVo;
	}

	@Override
	@Transactional
	public Boolean up(Long id) {
    	//1.查询出supId所对应的SKU信息，品牌的名字
		List<MallSkuInfo> mallSkuInfoList = iMallSkuInfoService.list(new LambdaQueryWrapper<MallSkuInfo>().eq(MallSkuInfo::getSpuId,id));
		//2.查询当前SKU的所有可检索的规格属性
		List<SkuEsModel.Attrs> searchAttrsList=null;
		List<MallProductAttrValue> mallProductAttrValueList=iMallProductAttrValueService.getListBySpuId(id);
		if(CollectionUtil.isNotEmpty(mallProductAttrValueList)){
			List<Long> attrIdLIst = mallProductAttrValueList.stream().map(item -> {
				return item.getAttrId();
			}).collect(Collectors.toList());
			//可检索的属性
			LambdaQueryWrapper<MallAttr> attrWrapper = new LambdaQueryWrapper<>();
			attrWrapper.in(MallAttr::getAttrId,attrIdLIst);
			attrWrapper.eq(MallAttr::getSearchType, AttrEnum.MALL_ATTR_SEARCH.getValue());
			List<MallAttr> mallAttrList = iMallAttrService.list(attrWrapper);
			if(CollectionUtil.isNotEmpty(mallAttrList)){
            //获取到支持检索的属性的属性ID
			List<Long> searchAttrIds = mallAttrList.stream().map(e -> e.getAttrId()).collect(Collectors.toList());
				HashSet<Long> searchAttrIdsSet = new HashSet<>(searchAttrIds);
				//取得支持检索的的Attrs，用来封装SkuEsModel的attrs属性
				searchAttrsList = mallProductAttrValueList.stream().filter(item -> {
					return searchAttrIdsSet.contains(item.getAttrId());
				}).map(item -> {
					SkuEsModel.Attrs attrs = new SkuEsModel.Attrs();
					attrs.setAttrId(item.getAttrId());
					attrs.setAttrName(item.getAttrName());
					attrs.setAttrValue(item.getAttrValue());
					return attrs;
				}).collect(Collectors.toList());
			}
		}
		//3.查询库存
		List<Long> skuInfoSkuIds = mallSkuInfoList.stream().map(MallSkuInfo::getSkuId).collect(Collectors.toList());
		if(CollectionUtils.isEmpty(skuInfoSkuIds)){
			throw new CustomException("请添加库存！");
		}
		List<SkuHasStockVo> skuHasStockData = iMallWareSkuService.getSkuHasStock(skuInfoSkuIds);

		Map<Long, Boolean> stockMap = skuHasStockData.stream().collect(Collectors.toMap(SkuHasStockVo::getSkuId, SkuHasStockVo::getHasStock));
		//可检索的属性
		List<SkuEsModel.Attrs> finalSearchAttrsList = searchAttrsList;
		//组装数据
		List<SkuEsModel> skuEsModelList = mallSkuInfoList.stream().map(item -> {
			//组装需要的数据
			SkuEsModel skuEsModel = new SkuEsModel();
			BeanUtils.copyProperties(item, skuEsModel);
			skuEsModel.setSkuPrice(item.getPrice());
			skuEsModel.setSkuImg(item.getSkuDefaultImg());
			skuEsModel.setHasStock(stockMap.get(item.getSkuId()));
			skuEsModel.setHotScore(0L);
			//品牌
			MallBrand mallBrand = iMallBrandService.getById(skuEsModel.getBrandId());
			skuEsModel.setBrandName(mallBrand.getName());
			skuEsModel.setBrandImg(mallBrand.getLogo());
			skuEsModel.setCatalogId(item.getCatalogId());
			MallCategory categoryEntity = iMallCategoryService.getById(skuEsModel.getCatalogId());
			skuEsModel.setCatalogName(categoryEntity.getName());

			//设置检索属性，attrs
			skuEsModel.setAttrs(finalSearchAttrsList);


			return skuEsModel;

		}).collect(Collectors.toList());
		Boolean aBoolean=null;
		try {
			 aBoolean = esProductSaveService.productUp(skuEsModelList);
		} catch (IOException e) {
			throw new CustomException("调用es保存失败！"+e.getMessage());
		}
		if(!aBoolean){
            //修改当前的SPU状态
			MallSpuInfo mallSpuInfo = new MallSpuInfo();
			mallSpuInfo.setId(id);
			mallSpuInfo.setPublishStatus(SpuEnum.MALL_PRODUCT_UP.getValue());
			return iMallSpuInfoService.updateById(mallSpuInfo);
		}
		return false;
	}
}
